﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace KATS_Client.FileNameData
{
    /// <summary>
    /// Find a matching folder for the file provided
    /// </summary>
    public static class FindFileLocation
    {
        /// <summary>
        /// Find a matching folder for the file
        /// </summary>
        /// <param name="filename">The filename to parse</param>
        /// <returns>The file location that matches or null if failed</returns>
        public static PredictionResult Parse(string filename)
        {
            FileNameInfo fileData = FileNameInfo.Parse(filename);

            if (fileData == null)
            {
                return null;
            }

            List<Client.FileSystemObject> directorys = new List<KATS_Client.Client.FileSystemObject>();


            // get a list of all sub directories displayed in the system
            foreach (UI.Window w in UI.WindowManager.Windows)
            {
                // for each window
                foreach (UI.Tab t in w.Tabs)
                {
                    // for each tab
                    if (!directorys.Contains(t.Directory) && !t.Directory.IsMyComputer)
                        directorys.Add(t.Directory);

                    foreach (Client.FileSystemObject fso in t.Directories)
                    {
                        if (!directorys.Contains(fso))
                            directorys.Add(fso);
                    }
                }
            }

            // find the most similar value
            int max = int.MinValue;
            Client.FileSystemObject maxObj = null;

            foreach (Client.FileSystemObject fso in directorys)
            {
                int ld = LevenshteinDistance.GetSimilarity(fso.Name, fileData.Series);
                if (ld > max)
                {
                    max = ld;
                    maxObj = fso;
                }
            }

            Client.FileSystemObject maxObj_B = maxObj;
            if (maxObj_B == null)
                maxObj_B = new Client.FileSystemObject("", false, Client.FileSystemObjectTypes.Directory);

            if (maxObj == null)
                return null;

            // the name of the folder
            string name = maxObj.Name;


            // the 2 regex expressions supported for sub directories
            Regex season_num_REGEX = new Regex("Season( )?[0-9]+", RegexOptions.IgnoreCase);
            Regex episodeSpread_REGEX = new Regex("[0-9]+-[0-9]+", RegexOptions.IgnoreCase);


            // used if there is a valid subdirectory to use
            Client.FileSystemObject targetDirectory = null;

            string[] subDirectories = Client.FileActions.Directories(maxObj);
            foreach (string s in subDirectories)
            {
                string subDirName = s.Replace(maxObj.Location + "\\", "");

                if (season_num_REGEX.IsMatch(subDirName))
                {
                    string regResult = season_num_REGEX.Match(subDirName).Value;
                    // it is a match to the format "Season 1"
                    Regex r = new Regex("[0-9]+", RegexOptions.IgnoreCase);

                    // the 1st number result
                    Match m = r.Match(regResult);
                    int seasonNum = int.Parse(m.Value);
                    if (seasonNum == fileData.Season)
                    {
                        // the season number is the same as the file's
                        // so add it to this directory
                        targetDirectory = new Client.FileSystemObject(s, maxObj.IsRemote, Client.FileSystemObjectTypes.Directory);
                        break;
                    }
                }
                else if (episodeSpread_REGEX.IsMatch(subDirName))
                {
                    // it is a match to the format 010-100

                    string regResult = episodeSpread_REGEX.Match(subDirName).Value;

                    Regex numbers = new Regex("[0-9]+", RegexOptions.IgnoreCase);

                    MatchCollection matches = numbers.Matches(regResult);

                    // get the 1st and 2nd numbers
                    int first = int.Parse(matches[0].Value);
                    int second = int.Parse(matches[1].Value);

                    if (fileData.Episode >= first && fileData.Episode <= second)
                    {
                        // then this file belongs in this directory
                        // as is between the min and max values for this directory
                        targetDirectory = new KATS_Client.Client.FileSystemObject(s, maxObj.IsRemote, Client.FileSystemObjectTypes.Directory);
                        break;
                    }
                }

            }

            if (targetDirectory != null)
            {
                // there is a special sub directory that should be used
                return new PredictionResult(targetDirectory, name, max);
            }
            else
            {
                // there is no special sub directory to use
                return new PredictionResult(maxObj, name, max);
            }

        }

    }
}
